/***************************************************************************
 *   mgpi_thread_test.c - MGPI Thread Control System Test	           *
 *   Copyright (C) 2008 by cmaster.matso                                   *
 *   cmaster.matso@gmail.com                                               *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#include <MGPI/mgpi.h>

typedef struct {
    float vertex[4];
} __vert_t;

int timing(long LENGTH) {
    float4 temp = MGPI_DEFAULT_VECTOR;
    __vert_t *verts = (__vert_t *) calloc(LENGTH, sizeof (__vert_t));
    int i;
    double _start;
    double _stop;

    float4x4 transform = MGPI_IDENTITY;
    transform[0][3] = 1.0f;
    transform[1][3] = 2.0f;
    transform[2][3] = -1.2f;

    for (i = 0; i < LENGTH; ++i) {
        verts[i].vertex[0] = 1.0f;
        verts[i].vertex[1] = -1.0f;
        verts[i].vertex[2] = 0.1f;
        verts[i].vertex[3] = 1.0f;
    }

    _start = (double) SDL_GetTicks() / 1000;

    for (i = 0; i < LENGTH; ++i) {
        MGPI_MatrixMulVect4(&temp, transform, verts[i].vertex);
        verts[i].vertex[0] = (temp[0] /= temp[3]);
        verts[i].vertex[1] = (temp[1] /= temp[3]);
        verts[i].vertex[2] = (temp[2] /= temp[3]);
        verts[i].vertex[3] = (temp[3] /= temp[3]);
    }

    _stop = (double) SDL_GetTicks() / 1000;

    fprintf(stdout, "Time for transforming %ld vertices: %2.3f seconds;\n", LENGTH, (_stop - _start));
    fprintf(stdout, "This means caluculations done upon %ld(aprox.) triangles in this time;\n", (LENGTH / 3));
    free(verts);
    return 0;
}

int thr_timing(void *t) {
    MGPI_Tree *tree = (MGPI_Tree *) t;

    return (timing(1000000L));
}

int main(int argc, char *argv[]) {
    MGPI_Tree *root = NULL;

    int outcome[3] = {0, 0, 0}, n, thrs[3];
    double _start;
    double _stop;

    MGPI_InitFramework();

    n = MGPI_GetThreadsNumber();
    fprintf(stdout, "Number of threads:  %d (main+%d)\n", n, (n - 1));

    fprintf(stdout, "Creating main subthreads...\n");

    _start = (double) SDL_GetTicks() / 1000;

    thrs[0] = MGPI_AddThread(&root, thr_timing, NULL);
    thrs[1] = MGPI_AddThread(&root, thr_timing, NULL);
    thrs[2] = MGPI_AddThread(&root, thr_timing, NULL);

    fprintf(stdout, "Number of root's children: %d\n", root->nchld);
    n = MGPI_GetThreadsNumber();
    fprintf(stdout, "Number of threads:  %d (main+%d)\n", n, (n - 1));

    SDL_WaitThread(MGPI_GetThread(root, thrs[0]), &outcome[0]);
    SDL_WaitThread(MGPI_GetThread(root, thrs[1]), &outcome[1]);
    SDL_WaitThread(MGPI_GetThread(root, thrs[2]), &outcome[2]);

    _stop = (double) SDL_GetTicks() / 1000;

    fprintf(stdout, "Global working time: %2.3f\n", (_stop - _start));
    n = MGPI_GetThreadsNumber();
    fprintf(stdout, "Number of threads:  %d (main+%d)\n", n, (n - 1));

    fprintf(stdout, "Deleting all main subthreads...\n");
    MGPI_DeleteThreads(root);

    fprintf(stdout, "Number of root's children: %d\n", root->nchld);
    n = MGPI_GetThreadsNumber();
    fprintf(stdout, "Number of threads:  %d (main+%d)\n", n, (n - 1));

    return 0;
}

